package com.mbti.youmore.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.mbti.youmore.common.exception.UserNotExistsException;
import com.mbti.youmore.entity.Chat;
import com.mbti.youmore.entity.User;
import com.mbti.youmore.mapper.UserMapper;
import com.mbti.youmore.service.ChatService;
import com.mbti.youmore.mapper.ChatMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.sql.Timestamp;
import java.util.*;

/**
 * @author Guqier
 * @description 针对表【t_chat】的数据库操作Service实现
 * @createDate 2024-05-08 20:30:45
 */
@Service
public class ChatServiceImpl extends ServiceImpl<ChatMapper, Chat>
        implements ChatService {

    @Autowired
    private ChatMapper chatMapper;

    @Autowired
    private UserMapper userMapper;

    /**
     * 把一次聊天消息插入表中
     * @param Chat 消息对象
     * @return boolean 发送成功与否
     * @throws UserNotExistsException
     */
    @Override
    @Transactional
    public boolean sendMsg(Chat Chat) throws UserNotExistsException {
        if (Chat.getUserId() == null || Chat.getToUserId() == null || Chat.getContent().equals("")) {
            return false;
        }

        User curr = userMapper.selectById(Chat.getUserId());
        User target = userMapper.selectById(Chat.getToUserId());
        if (curr == null || target == null) {
            throw new UserNotExistsException("用户不存在！");
        }

        Chat.setTime(new Timestamp(new Date().getTime()));
        Chat.setIsRead(0);

        int i = chatMapper.insert(Chat);
        return i == 1;
    }

    /**
     * 获取 userId 与 targetUserId 的所有聊天记录
     * @param userId       当前用户ID
     * @param targetUserId 目标用户ID
     * @return Chat 列表
     * @throws UserNotExistsException
     */
    @Override
    @Transactional
    public List<Chat> getMsg(Integer userId, Integer targetUserId) throws UserNotExistsException {
        User curr = userMapper.selectById(userId);
        User target = userMapper.selectById(targetUserId);
        if (curr == null || target == null) {
            throw new UserNotExistsException("用户不存在！");
        }
        List<Chat> msgList = chatMapper.selectList(new LambdaQueryWrapper<Chat>().eq(Chat::getUserId, userId).eq(Chat::getToUserId, targetUserId));
        msgList.addAll(chatMapper.selectList(new LambdaQueryWrapper<Chat>().eq(Chat::getUserId, targetUserId).eq(Chat::getToUserId, userId)));
        msgList.sort(Comparator.comparing(Chat::getTime)); // 根据消息时间排序

        // 标记消息为已读
        for (Chat Chat : msgList) {
            if (Chat.getIsRead().equals(0) && Chat.getToUserId().equals(userId)) {
                Chat.setIsRead(1);
                chatMapper.updateById(Chat);
            }
        }

        return msgList;
    }

    /**
     * 获取 userId 的所有聊天缩略
     * @param userId 当前用户ID
     * @return 聊天缩略映射对象列表
     */
    @Override
    public List<Map<String, Object>> getChatList(Integer userId) {
        List<Map<String, Object>> res = new ArrayList<>();

        List<Chat> msgList1 = chatMapper.selectList(new LambdaQueryWrapper<Chat>().eq(Chat::getUserId, userId));// 所有以 userId 作为发送者的 Chat
        List<Chat> msgList2 = chatMapper.selectList(new LambdaQueryWrapper<Chat>().eq(Chat::getToUserId, userId));// 所有以 userId 作为接收者的 Chat

        // 去重，目的是得到所有与 userId 聊过天的 targetUserId
        LinkedHashSet<Integer> set = new LinkedHashSet<>();
        for (Chat Chat : msgList1) {
            set.add(Chat.getToUserId());
        }
        for (Chat Chat : msgList2) {
            set.add(Chat.getUserId());
        }
        List<Integer> targetUserId = new ArrayList<>(set);

        // 开始生成聊天缩略映射对象
        for (Integer id : targetUserId) {
            Chat latestMsg = ChatServiceImpl.getLatestMsg(msgList1, msgList2, id);
            User user = userMapper.selectById(id);

            Map<String, Object> map = new LinkedHashMap<>();
            map.put("userId", user.getUserId());
            map.put("username", user.getUsername());
            map.put("nickname", user.getNickname());
            map.put("profilePic", user.getProfilePic());
            map.put("latestTime", latestMsg.getTime().toString());
            map.put("latestMsg", latestMsg.getContent());

            // 获取未读消息数
            List<Chat> msgList = chatMapper.selectList(new LambdaQueryWrapper<Chat>().eq(Chat::getUserId, id).eq(Chat::getToUserId, userId));
            int cnt = 0;
            for (Chat Chat : msgList) {
                if (Chat.getIsRead() == 0) {
                    cnt++;
                }
            }
            map.put("count", cnt);
            res.add(map);
        }
        return res;
    }

    /**
     * 获取 userId 的所有聊天缩略
     * @param chatId 消息ID
     * @return 聊天缩略映射对象列表
     */
    @Override
    @Transactional
    public boolean setIsRead(Integer chatId) {
        Chat Chat = chatMapper.selectById(chatId);
        if (Chat == null) {
            return false;
        }
        Chat.setIsRead(1);
        int i = chatMapper.updateById(Chat);
        return i == 1;
    }

    /**
     * 删除 userId 跟 targetUserId 的所有聊天记录
     * @param userId       当前用户ID
     * @param targetUserId 目标用户ID
     * @return 聊天消息的数量
     * @throws UserNotExistsException
     */
    @Override
    @Transactional
    public int deleteChat(Integer userId, Integer targetUserId) throws UserNotExistsException {
        User target = userMapper.selectById(targetUserId);
        if (target == null) {
            throw new UserNotExistsException("用户不存在！");
        }

        int d1 = chatMapper.delete(new LambdaQueryWrapper<Chat>().eq(Chat::getUserId, userId).eq(Chat::getToUserId, targetUserId));
        int d2 = chatMapper.delete(new LambdaQueryWrapper<Chat>().eq(Chat::getUserId, targetUserId).eq(Chat::getToUserId, userId));
        return d1 + d2;
    }

    /**
     * 删除一条聊天记录
     * @param msgId 消息ID
     * @return 删除成功与否
     */
    @Override
    public int deleteChatMsg(Integer msgId) {
        return chatMapper.deleteById(msgId);
    }

    /**
     * 获取 userId 的未读消息数
     * @param userId 当前用户ID
     * @return 未读消息数
     */
    @Override
    public int getNotReadCount(Integer userId) {
        return Math.toIntExact(chatMapper.selectCount(new LambdaQueryWrapper<Chat>().eq(Chat::getToUserId, userId).eq(Chat::getIsRead, 0)));
    }

    /**
     * 获取当前对象与 targetUserId 的一次最新消息
     * @param list1        targetUserId 作为发送者且当前用户作为接收者的 Chat 列表
     * @param list2        targetUserId 作为接收者且当前用户作为发送者的 Chat 列表
     * @param targetUserId 当前用户的聊天对象Id
     * @return 当前用户与 targetUserId 的最新一次 Chat
     */
    private static Chat getLatestMsg(List<Chat> list1, List<Chat> list2, Integer targetUserId) {
        Chat latestMsg = null;
        for (Chat Chat : list1) {
            if (Chat.getToUserId().equals(targetUserId)) {
                if (latestMsg == null) {
                    latestMsg = Chat;
                } else {
                    if (latestMsg.getTime().getTime() < Chat.getTime().getTime()) {
                        latestMsg = Chat;
                    }
                }
            }
        }
        for (Chat Chat : list2) {
            if (Chat.getUserId().equals(targetUserId)) {
                if (latestMsg == null) {
                    latestMsg = Chat;
                } else {
                    if (latestMsg.getTime().getTime() < Chat.getTime().getTime()) {
                        latestMsg = Chat;
                    }
                }
            }
        }
        return latestMsg;
    }

}




